import Vue from 'vue'
import Vuex from 'vuex'
import { nanoid } from 'nanoid'
import day from 'dayjs'
import calculation from '../common/calculation'
import clone from '@/common/clone'
import { httpGet, httpPOST } from '@/common/req'

Vue.use(Vuex)

const store = new Vuex.Store({
  state: {
    recordList: [],
    tagList: [],
    ledgers: [],
    ledgerLogos: [],
    record: null,
    today: null,
    start: '',
    end: '',
    hasLogin: false,
    userInfo: null
  },
  getters: {
    // tags
    findTag(state) {
      return function(id) {
        return state.tagList.filter(function(t) { return t.id === id })[0]
      }
    },
    getItemName(state) {
      return function(id) {
        var tag = state.tagList.filter(function(tag) { return tag.id === id })[0]
        return tag ? tag.name : ''
      }
    },
    getBookUserIcon(state) {
      return function(id) {
        const avatarUrl = id === state.userInfo.id ? state.userInfo.avatarUrl : (state.ledgerLogos.find(i => i.id === id) || {}).avatarUrl
        return avatarUrl || 'https://s.benlv.top/upload/1714468005-logo.png'
      }
    },
    getSeries(state, getters) {
      return (data) => {
        const groupedByKey = (data || []).reduce((acc, obj) => {
          const key = getters.getItemName(obj.tagIds[0])
          if (!acc[key]) {
            acc[key] = []
          }
          acc[key].push(obj)
          return acc
        }, {})
        const series = Object.keys(groupedByKey).map(name => {
          const data = groupedByKey[name].reduce((accumulator, currentValue) => {
            return calculation.add(accumulator, currentValue.amount || 0)
          }, 0)
          return { data, name, labelShow: false }
        })
        return series
      }
    },
    getItemIcon(state) {
      return function(id) {
        var tag = state.tagList.filter(function(tag) { return tag.id === id })[0]
        return tag ? tag.iconName : '9999'
      }
    },
    // 获取 收入的标签
    income(state) {
      return state.recordList.filter(function(item) { return item.category === '+' })
    },
    // 获取 今日收入的金额
    incomeMoney() {
      return function(today) {
        var todayIncome = store.getters.income
          .filter(function(item) { return day(item.createdAt).format('MM') === today })
        return todayIncome.map(function(item) { return item.amount })
      }
    },
    // 获取 支出的标签
    expenses(state) {
      return state.recordList.filter(function(item) { return item.category === '-' })
    },
    // 获取 本月支出的金额
    expensesMoney() {
      return function(today) {
        var mouthExpenses = store.getters.expenses
          .filter(function(item) { return day(item.createdAt).format('DD') === today })
        return mouthExpenses.map(function(item) { return item.amount })
      }
    },
    // 获取当日的总收入或总支出
    dayTotalList: (state) => (type) => {
      // 日期从大到小排
      const newList = [...state.recordList]
        .filter(r => r.category === type)
        .sort((a, b) => day(b.createdAt).valueOf() - day(a.createdAt).valueOf()).map(i => {
          const date = new Date(i.createdAt)
          const day = date.getDate()
          let month = date.getMonth()
          i.date = `${++month > 9 ? month : `0${month}`}/${day > 9 ? day : `0${day}`}`
          return i
        })
      if (newList.length === 0) {
        return []
      }
      const today = new Date(state.end.getTime() - 1)
      const result = {}
      for (let i = 0; i <= parseInt(day(today).format('DD')) - 1; i++) {
        const days = day(today).subtract(i, 'day').format('MM/DD')
        const d = newList.filter(i => i.date === days)
        if (!result[days] && d.length > 0) {
          result[days] = d.reduce((pre, acc) => {
            return calculation.add(pre, acc.amount || 0)
          }, 0)
        }
      }
      return result
    }
  },
  mutations: {
    setDate: (state, param) => {
      state.start = param.start
      state.end = param.end
      uni.setStorageSync('LG', param.start)
    },
    // records
    fetchRecords: (state) => {
      if (!state.hasLogin) { return }
      const _id = state.userInfo.ledger.u_id
      const param = { start: state.start, end: state.end, _id }
      httpPOST({ url: 'book/records', param }).then(function(_a) {
        var err = _a[0]; var res = _a[1]
        if (!err) {
          var localTags = res.data
          localTags = localTags.map(function(i) {
            var id = i.tag.id
            delete i.tag
            return Object.assign({ tagIds: [id] }, i)
          })
          state.recordList = localTags || []
        }
      })
    },
    delRecode(state, { id }) {
      const url = 'book/record/rm'
      httpPOST({ url, param: { id } }).then(([err, res]) => {
        if (res && res.data) {
          state.recordList = state.recordList.filter(i => i.id !== id)
        }
      })
    },
    fetchLedgers(state) {
      const u_id = state.userInfo.id + ''
      const url = 'book/ledgers'
      httpPOST({ url, param: { u_id } }).then(([err, res]) => {
        if (res && res.data) {
          state.ledgers = res.data.map(i => {
            i.name = Object.keys(i.u_id).length > 1 ? '家庭账本' : '个人账本'
            return i
          })
        }
      })
    },
    fetchLedgerLogo(state) {
      const _in = state.userInfo.ledger.u_id
      const url = 'book/account/logo'
      httpPOST({ url, param: { _in } }).then(([err, res]) => {
        if (res && res.data) {
          state.ledgerLogos = res.data
        }
      })
    },
    updateLedger(state, { b_id, call }) {
      const user = state.userInfo.user
      const url = 'book/account/ledger'
      httpPOST({ url, param: { user, b_id } }).then(([err, res]) => {
        if (res && res.data) {
          const token = state.userInfo.token
          const d = Object.assign({ token }, res.data)
          d.ledger.u_id = d.ledger.u_id ? Object.keys(d.ledger.u_id) : [d.id]
          state.userInfo = d
          uni.setStorageSync('LGS', d)
          // console.error(res.data)
          call()
        }
      })
    },
    login(state, provider) {
      state.hasLogin = true
      provider.ledger.u_id = provider.ledger.u_id ? Object.keys(provider.ledger.u_id) : [provider.id]
      state.userInfo = provider
      uni.setStorageSync('LGS', provider)
    },
    loginOut(state) {
      state.hasLogin = false
      state.userInfo = null
      uni.removeStorageSync('LGS')
    },
    loginCheck(state) {
      const user = state.userInfo.user
      const url = 'book/account/check'
      httpPOST({ url, param: { user } }).then(([err, res]) => {
        if (res && res.data) {
          console.error(res.data)
        }
      })
    },
    bookRecord: (state) => {
      if (!state.hasLogin) { return }
      const _id = state.userInfo.ledger.u_id
      const param = { start: state.start, end: state.end, _id }
      httpPOST({ url: 'book/record', param }).then(function(_a) {
        var err = _a[0]; var res = _a[1]
        if (!err) {
          var expense = res.expense
          var income = res.income
          if (income && expense) {
            expense = expense.data
            income = income.data
            state.record = { expense, income }
          }
        }
      })
    },
    todayRecord: (state) => {
      if (!state.hasLogin) { return }
      const start = new Date()
      start.setHours(0, 0, 0, 0)
      const end = new Date(start.getTime())
      end.setDate(end.getDate() + 1)
      const _id = state.userInfo.ledger.u_id
      const param = { start, end, _id }
      httpPOST({ url: 'book/record', param }).then(function(_a) {
        var err = _a[0]; var res = _a[1]
        if (!err) {
          var expense = res.expense
          var income = res.income
          if (income && expense) {
            expense = expense.data
            income = income.data
            state.today = { expense, income }
          }
        }
      })
    },
    createRecord: (state, record) => {
      if (!state.hasLogin) { return }
      if (!record.tagId && record.tagId !== 0) {
        Vue.prototype.$api.alert('请选择标签!')
        return
      }
      if (record.amount <= 0) {
        Vue.prototype.$api.alert('请输入金额!')
        return
      }
      var newRecord = clone(record)
      newRecord.tagIds = newRecord.tagId
      delete newRecord.tagId
      const _id = state.userInfo.id
      newRecord._id = _id
      console.error(newRecord)
      httpPOST({ url: 'book/record/add', param: newRecord }).then(function(_a) {
        var err = _a[0]; var res = _a[1]
        if (err) { return }
        state.recordList.push(newRecord)
        Vue.prototype.$api.alert('保存成功')
        Vue.prototype.$api.reload()
      })
    },
    fetchTags: (state) => {
      httpGet({ url: 'book/tagList' }).then(function(_a) {
        var err = _a[0]; var res = _a[1]
        if (!err) {
          var localTags = res.data
          state.tagList = localTags
        }
      })
    },
    createTag(state, payload) {
      var name = payload.name; var iconName = payload.iconName; var mold = payload.mold
      state.tagList.push({ id: nanoid(10), name, iconName, mold })
      Vue.prototype.$api.reload()
    },
    removeTag(state, id) {
      var index = -1
      for (var i = 0; i < state.tagList.length; i++) {
        if (state.tagList[i].id === id) {
          index = i
          break
        }
      }
      state.tagList.splice(index, 1)
      Vue.prototype.$api.reload()
    },
    updateTag(state, payload) {
      var id = payload.id; var name = payload.name; var iconName = payload.iconName; var mold = payload.mold
      var newTags = state.tagList.map(function(tag) { return tag.id === id ? { id: id, name: name, iconName: iconName, mold: mold } : tag })
      state.tagList = newTags
      Vue.prototype.$api.reload()
    }
  }
})

export default store
